/**
 * 
 */
package edu.umd.clip.lm.questions;

import org.w3c.dom.*;
import edu.umd.clip.lm.factors.*;
import edu.umd.clip.lm.model.data.Context;
import edu.umd.clip.lm.model.*;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public class IdentityQuestion extends Question {
	public static final String XML_PARAM_NAME = "param";
	
	private int value;
	
	public IdentityQuestion(byte time, byte idx, int value) {
		super(time, false);
		this.index = idx;
		this.value = value;
	}
	
	public IdentityQuestion(Element xmlnode) {
		super(xmlnode);
		Element node = (Element) xmlnode.getElementsByTagName(XML_PARAM_NAME).item(0);
		this.value = Integer.parseInt(node.getTextContent());
	}
	
	public static Question fromXML(Element xmlnode) {
		return new IdentityQuestion(xmlnode);
	}
	
	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#createXML(org.w3c.dom.Document)
	 */
	@Override
	public Element createXML(Document doc) {
		Element param = doc.createElement(XML_PARAM_NAME);
		param.setTextContent(Integer.toString(value));
		Element element = super.createXML(doc);
		element.appendChild(param);
		return element;
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#getQuestionType()
	 */
	@Override
	public int getQuestionType() {
		return IDENTITY_QUESTION;
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#test(edu.umd.clip.lm.model.training.Context)
	 */
	@Override
	public boolean test(Context ctx) {
		long tuple = ctx.data[ctx.data.length + getTimeOffset()];
		return FactorTuple.getValue(tuple, index) == value;
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#implication(edu.umd.clip.lm.questions.Question, boolean)
	 */
	@Override
	public Boolean implication(Question q, boolean value) {
		if (q.getQuestionType() != IDENTITY_QUESTION) return null;
		IdentityQuestion iq = (IdentityQuestion) q;
		if (iq.index == this.index) {
			if (iq.value != this.value) {
				return value ? Boolean.FALSE : null;
			}
			return Boolean.valueOf(value);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#testCut(java.util.Collection)
	 */
	@Override
	public TestResult test(AbstractProbTree[] context) {
		AbstractProbTree tree = context[-(1 + getTimeOffset())];
		return new TestResult(FactorTuple.getValue(tree.getTuple(), index) == value);
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#testCut(java.util.Collection)
	 */
	@Override
	public TestResult test(AbstractProbTree tree) {
		return new TestResult(FactorTuple.getValue(tree.getTuple(), index) == value);
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		FactorDescription desc = Experiment.getInstance().getTupleDescription().getDescription(index);
		String s = String.format("[IdentityQuestion: time=%d val=%s-%s]", 
				timeOffset, desc.getId(), desc.getDictionary().getWord(value));
		return s;
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#toShortString()
	 */
	@Override
	public String toShortString() {
		long tuple = FactorTuple.setValue(0, index, value);
		return super.toShortString() + ' ' + FactorTuple.toStringNoNull(tuple);
	}

	public int getValue() {
		return value;
	}

}
